package beans;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import model.User;
import conversions.Conversions;
import dao.ServerLogEntryDao;
import dao.UserDao;
import dto.DTOUser;
import enumerations.LogType;

/**
 * Session Bean implementation class UserBean
 */
@Stateless
public class UserBean implements UserBeanRemote {

	@PersistenceContext
	EntityManager em;

	@EJB
	Conversions conv;

	@EJB
	ServerLogEntryDao daoSle;

	@EJB
	UserDao daoUser;

	@EJB
	SendEmailLocalBean selb;

	/**
	 * Default constructor.
	 */
	public UserBean() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @author zahariem second author Description zahariem: added op to
	 *         serverLog
	 */
	@Override
	public void addUser(DTOUser uDto, String language) {
		User user = conv.userFromDto(uDto);
		daoUser.insertUser(user);	
		selb.sendNotificationEmail(uDto, language);

		User author = daoUser.getAdminUser();
		String content = "Created user: " + user.getId() + " " + user.getName()
				+ " " + user.getUserType();
		daoSle.insertOpToLog(LogType.create_user, content, new Date(), author);
	}

	/**
	 * @author ieneir 
	 * creat
	 * @author zahariem second author Description zahariem: added op to
	 *         serverLog
	 */
	@Override
	public void invalidateUser(Integer uId) {
		daoUser.invalidateUser(uId);
		
		User author = daoUser.getAdminUser();
		String content = "Invalidate user: " + uId + " "
				+ daoUser.getUserById(uId).getName();
		daoSle.insertOpToLog(LogType.create_user, content, new Date(), author);
	}

	/**
	 * @author ieneir
	 * schimba tipul unui user din invalid in valid
	 */
	@Override
	public void validateUser(Integer id) {
		daoUser.validateUser(id);
		
		User author = daoUser.getAdminUser();
		String content = "Validate user: " + id + " "
				+ daoUser.getUserById(id).getName();
		daoSle.insertOpToLog(LogType.create_user, content, new Date(), author);
	}
	
	/**
	 * @author fodorl
	 * @return List<DTOUser> returneaza toti userii din baza de date
	 */

	public List<DTOUser> getAllUsersDTO() {
		List<User> users = daoUser.getAllUsers();
		List<DTOUser> usersDTO = new ArrayList<DTOUser>();
		for (User user : users) {
			DTOUser dUser =conv.fromUserToDto(user);
			dUser.setSelected(dUser.getType().equals("invalidated"));
			usersDTO.add(dUser);
		}
		return usersDTO;
	}

	/**
	 * @author ieneir
	 * 
	 */
	@Override
	public DTOUser getUser(int uId) {
		User user = daoUser.getUserById(uId);
		DTOUser uDto = conv.fromUserToDto(user);
		return uDto;
	}

		/**
		 * @author ieneir
		 */
	@Override
	public boolean existsNameInDB(String enteredName) {
		return daoUser.existsNameInDB(enteredName);
	}
	
	/**
	 * @author ieneir
	 */
	
	@Override
	public boolean existsEmailInDB(String enteredEmail) {
		return daoUser.existsEmailInDB(enteredEmail);
	}

	/**
	 * @author fodorl
	 * @return boolean
	 * @param int
	 * @param int returneaza true daca user-ul cu id-ul dat e supervisor pe
	 *        repository-ul cu id-ul dat
	 */

	@Override
	public boolean isSupervisor(int idUser, int idRepository) {
		return daoUser.isSupervisor(idUser, idRepository);
	}

	/**
	 * @author fodorl
	 * @return int returneaza id-ul userului cu numele dat
	 */

	public int getUserIdByName(String userName) {
		return daoUser.getIdUserByName(userName);
	}
	
	/**
	 * @author fodorl
	 * @param idRepository
	 * @return List<DTOUser>
	 * returneaza o lista cu userii activi dintr-un repository
	 */
	
	public List<DTOUser> getValidatedUsersFromRepository(int idRepository){
		List<User> users = daoUser.getValidatedUsersFromRepository(idRepository);
		List<DTOUser> usersDTO = new ArrayList<DTOUser>();
		for (User user : users) {
			usersDTO.add(conv.fromUserToDto(user));
		}
		return usersDTO;
	}
	

	/**
	 * @author fodorl
	 * @return List<DTOUser>
	 * returneaza o lista cu userii care nu fac parte dintr-un anumit  repository
	 */
	
	public List<DTOUser> getUsersNotInRepository(int idRepository){
		List<User> users = daoUser.getUsersNotInRepository(idRepository);
		List<DTOUser> usersDTO = new ArrayList<DTOUser>();
		for (User user : users) {
			usersDTO.add(conv.fromUserToDto(user));
		}
		return usersDTO;
	}

	/**
	 * @author ieneir modifica datele unui user
	 */
	
	@Override
	public void updateUser(DTOUser dUser) {
		User user = (User) em.find(User.class, dUser.getId());
		user.setName(dUser.getName());
		user.setEmail(dUser.getEmail());
		user.setPassword(dUser.getPassword());
		user.setTelephone(dUser.getTelephone());
		em.merge(user);
		
		User author = daoUser.getAdminUser();
		String content = "Modify user profile: " + user.getId() + " "
				+ user.getName();
		daoSle.insertOpToLog(LogType.modify_user, content, new Date(), author);
	}

	/**
	 * @author ieneir
	 * selectare useri dupa nume
	 */
	
	@Override
	public List<DTOUser> getAllUsersDTOStartingWith(String searchText) {
		List<User> users;
		if (searchText==null)
			users = daoUser.getAllUsersAndInvalidated();
		else
			users = daoUser.getAllUsersStartingWith(searchText);
		
		List<DTOUser> usersDTO = new ArrayList<DTOUser>();
		for (User user : users) {
			DTOUser dUser =conv.fromUserToDto(user);
			dUser.setSelected(dUser.getType().equals("invalidated"));
			usersDTO.add(dUser);
		}
		return usersDTO;
	}
	
	
	/**
	 * @author fodorl
	 * @param String
	 * @return DTOUser
	 * returneaza userul cu numele introdus
	 */

	@Override
	public DTOUser getUserByName(String userName) {
		User user = daoUser.getUserByName(userName);
		
		return conv.fromUserToDto(user);
	}
	
	/**
	 * 
	 * @author rusho+zahariem
	 * @param id userId 
	 * @param email userEmail
	 * 
	 */
	
	@Override
	public void setEmailNew(int id, String email) {
		daoUser.setProfileEmail(id, email);
		String content="User profile email modified";
		daoSle.insertOpToLog(LogType.modify_user, content, new Date(), daoUser.getUserById(id));
	}

	/**
	 * 
	 * @author rusho
	 * @param id userId
	 * @return email from DB
	 * 
	 */
	
	@Override
	public String getEmail(Integer id) {
		return daoUser.getEmailbyId(id);
		
	}
	
	/**
	 * @author rusho+zahariem
	 * @param id userId
	 * @param enteredPhone new Phone no
	 * 
	 */

	@Override
	public void setPhoneNew(Integer id, String enteredPhone) {
		daoUser.setProfilePhone(id, enteredPhone);
		
		String content="User profile phone modified";
		daoSle.insertOpToLog(LogType.modify_user, content, new Date(), daoUser.getUserById(id));
	}

	/**
	 * @author rusho
	 * @param id userId
	 * @return phone from DB
	 * 
	 */
	
	@Override
	public String getPhone(Integer id) {
		
		return daoUser.getPhoneByID(id);
	}

}
